package io.github.annyylxyms.gynregistry.cluster;

import io.github.annyylxyms.gynregistry.GynRegistryConfigProperties;
import io.github.annyylxyms.gynregistry.service.GynRegistryService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;

import java.util.ArrayList;
import java.util.List;

/**
 * Registry Cluster
 * 探活（选之前死了，选完子节点或主节点死了）、选取主节点
 */
@Slf4j
public class Cluster {
    @Value("${server.port}")
    String port;

    String host;

    Server MYSELF;

    GynRegistryConfigProperties registryConfigProperties;


    /**
     * -- GETTER --
     *  获取当前所有服务节点信息
     *
     * @return
     */
    @Getter
    private List<Server> servers;


    public Cluster(GynRegistryConfigProperties registryConfigProperties) {
        this.registryConfigProperties = registryConfigProperties;
    }

    /**
     * 拿到配置里的serverlist
     */
    public void init() {
        //InetAddress.getLocalHost().getHostAddress();有个bug，可能获取到本地虚拟子网的IP
        //引用InetUtils的springcloud包需要和本地springboot包版本一致
        try {
            host = new InetUtils(new InetUtilsProperties()).findFirstNonLoopbackHostInfo().getIpAddress();
            log.info("====> findFirstNonLoopbackHostInfo 找到第一个非回环地址是: " + host);
        } catch (Exception e) {
            host = "127.0.0.1";
        }

        MYSELF = new Server("http://" + host + ":" + port, true, false, -1L);
        log.info("====> MYSELF: " + MYSELF);

        initServers();
        new ServerHealth(this).checkServerHealth();

    }

    private void initServers() {
        //在方法内初始化，而不是在局部变量上直接初始化，可以防止有并发问题
        List<Server> servers = new ArrayList<>();
        for (String url : registryConfigProperties.getServerList()) {
            Server server = new Server();
            if (url.contains("localhost")) {
                url = url.replace("localhost", host);
            } else if (url.contains("127.0.0.1")) {
                url = url.replace("127.0.0.1", host);
            }
            if (url.equals(MYSELF.getUrl())) {
                servers.add(MYSELF);
            } else {
                server.setUrl(url);
                server.setStatus(false);
                server.setLeader(false);
                //-1表示初始化
                server.setVersion(-1L);
                servers.add(server);
            }
        } // todo ...

        this.servers = servers;
    }

    /**
     * 返回当前自己这个服务
     * @return
     */
    public Server self() {
        MYSELF.setVersion(GynRegistryService.VERSION.get());
        return MYSELF;
    }

    /**
     * 获取当前主节点
     * @return
     */
    public Server leader() {
        return this.servers.stream().filter(Server::isStatus)
                .filter(server -> server.isLeader()).findFirst().orElse(null);
    }

}
